package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.huanxin.HuanXinTemplate;
import com.itheima.domain.db.Question;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Friend;
import com.itheima.domain.mongo.RecommendUser;
import com.itheima.domain.vo.*;
import com.itheima.service.db.QuestionService;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.FriendService;
import com.itheima.service.mongo.RecommendUserService;
import com.itheima.service.mongo.UserLocationService;
import com.itheima.service.mongo.VisitorService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class MakeFriendManager {

    @Reference
    private RecommendUserService recommendUserService;

    @Reference
    private UserInfoService userInfoService;

    @Reference
    private QuestionService questionService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Reference
    private UserLocationService userLocationService;

    @Reference
    private VisitorService visitorService;
    /**
     * 查询今日佳人
     * 1.获取当前登录用户的id
     * 2.查询给当前用户推荐的人是谁  RecommendUser
     * 3.RecommendUser 有可能为空    构造假数据
     * 4.根据RecommendUser    查询出被推荐人的基础信息
     * 5.封装vo对象返回
     * @return
     */
    public RecommendUserVo findRecommendUserByUserId() {

        //1.获取当前登录用户的id
        Long loginUserId = UserHolder.getId();

        //2.查询给当前用户推荐的人是谁  RecommendUser
        RecommendUser recommendUser = recommendUserService.findRecommendUserByUserId(loginUserId);

        if (recommendUser == null) {
            //3.RecommendUser 有可能为空    构造假数据
            recommendUser = new RecommendUser();
            recommendUser.setToUserId(loginUserId);
            recommendUser.setUserId(1L);//推荐默认用户
            recommendUser.setScore(99d);//推荐的默认缘分值

        }
        //4.根据RecommendUser    查询出被推荐人的基础信息
        UserInfo userInfo = userInfoService.findById(recommendUser.getUserId());
        //5.封装vo对象返回
        RecommendUserVo vo = new RecommendUserVo();
        vo.setUserInfo(userInfo);
        vo.setFateValue(recommendUser.getScore().longValue());
        return vo;
    }

    /**
     * 查询推荐好友
     * 1.获得用户的id
     * 2.调用service进行查询 返回PageBeanVo
     * 3.获得集合对象
     * 4.判断集合是否为空   如果为空    构建假数据
     * 5.判断集合是否为空   如果不为空   遍历数据
     * 6.根据遍历的推荐用户查询 用户的基础信息
     * 7.返回
     */
    public PageBeanVo findRecommendUser(Integer pageNumber, Integer pageSize) {

        //1.获得用户的id
        Long loginUserId = UserHolder.getId();

        //2.调用service进行查询 返回PageBeanVo
        PageBeanVo pageBeanVo = recommendUserService.findRecommendUser(pageNumber, pageSize, loginUserId);
        //3.获得集合对象
        List<RecommendUser> items = (List<RecommendUser>) pageBeanVo.getItems();
        //4.判断集合是否为空   如果为空    构建假数据
        if (CollectionUtil.isEmpty(items)) {
            items = new ArrayList<>();
            for (int i = 2; i <=12 ; i++) {//推荐10个用户
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setToUserId(loginUserId);
                recommendUser.setUserId(Long.valueOf(i));//推荐默认用户
                recommendUser.setScore(RandomUtil.randomDouble(60,90));//推荐的默认缘分值
                items.add(recommendUser);
            }
        }
        List<RecommendUserVo> voList = new ArrayList<>();
        //5.判断集合是否为空   如果不为空   遍历数据
        for (RecommendUser recommendUser : items) {
            //6.根据遍历的推荐用户查询 用户的基础信息
            UserInfo userInfo = userInfoService.findById(recommendUser.getUserId());
            //6.1根据基础信息构建   RecommendUserVo对象
            RecommendUserVo vo = new RecommendUserVo();
            vo.setUserInfo(userInfo);
            vo.setFateValue(recommendUser.getScore().longValue());
            voList.add(vo);
        }

        //7.返回
        pageBeanVo.setItems(voList);

        return pageBeanVo;
    }

    /**
     * 查询推荐用户详情
     * @param recommendUserId
     * @return
     */
    public RecommendUserVo findPersonalInfo(Long recommendUserId) {
        //1.获得当前登录人的id
        Long loginUserId = UserHolder.getId();
        //2.根据loginUserId 和 recommendUserId查询缘分值
        RecommendUser recommendUser = recommendUserService.findRecommendUser(loginUserId, recommendUserId);

        if (recommendUser == null) {//此处判断只是为了不报错，否则新用户点击推荐用户肯定空指针异常
            recommendUser = new RecommendUser();
            recommendUser.setScore(RandomUtil.randomDouble(60,90));
        }
        //3.查询用户基础信息
        UserInfo userInfo = userInfoService.findById(recommendUserId);
        //返回
        RecommendUserVo vo = new RecommendUserVo();
        vo.setUserInfo(userInfo);//用户信息
        vo.setFateValue(recommendUser.getScore().longValue());
        return vo;
    }

    /**
     * 查询陌生人问题
     * @param userId
     * @return
     */
    public String findStrangerQuestion(Long userId) {
        //1.查询问题对象
        Question question = questionService.findByUserId(userId);

        if (question == null) {
            //2.为空
            question = new Question();
            question.setStrangerQuestion("你喜欢大海还是蓝天？");
        }
        //3.返回
        return question.getStrangerQuestion();
    }

    /**
     * 最近访客
     * 1.获得当前登录用户的id
     * 2.获得上次登录时间（需要判断是否为空）
     * 3.如果为空   直接返回空结合即可，同时存入一个当前登录时间
     * 4.如果不为空  根据用户id查询    和   上一次时间查询访客（此处返回值为List<访客id>）
     * 5.根据访客id查询UserInfo表获得基础信息
     * 6.将基础信息封装给VisitorVo
     * 7.更新本次缓存的登录时间
     * @return
     */
    public List<VisitorVo> findVisitor() {
        //1.获得当前用户的id
        Long userId = UserHolder.getId();
        //2.获得上次登录时间(需要判断是否为空)
        String key = ConstantUtil.LAST_ACCESS_TIME + userId;
        String lastTime = stringRedisTemplate.opsForValue().get(key);
        if(StrUtil.isEmpty(lastTime)){
            //3.如果为空 直接返回空集合即可,同时存入一个当前登录的时间
            stringRedisTemplate.opsForValue().set(key , System.currentTimeMillis() +"");
            return null;
        }
        //4.如果不为空 根据用户的id查询 和 上一次时间查询访客的列表记录(此处返回值为List<访客id>)
        List<Long>  visitorIds =  visitorService.findVisitorIds(userId ,lastTime );
        //创建返回值
        List<VisitorVo> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(visitorIds)){
            for (Long visitorId : visitorIds) {
                //5.根据访客的id 查询UserInfo表获得基础信息
                UserInfo userInfo = userInfoService.findById(visitorId);
                //6.将基础信息封装给 VisitorVo
                VisitorVo vo = new VisitorVo();
                //7.查询缘分值
                RecommendUser recommendUser = recommendUserService.findRecommendUser(userId, visitorId);

                vo.setUserInfo(userInfo);
                if(recommendUser == null){//防止没有查询到数据 报错
                    vo.setFateValue(RandomUtil.randomLong(60,90));
                }else{
                    vo.setFateValue(recommendUser.getScore().longValue());
                }
                voList.add(vo);
            }

        }
        //7.更新本次缓存的登录时间
        //TODO 此处有争议  更新缓存的时间 设定
        //stringRedisTemplate.opsForValue().set(key , System.currentTimeMillis() +"");
        return voList;
    }

    /**
     * 上传位置
     * @param latitude
     * @param longitude
     * @param addrStr
     */
    public void saveOrUpdateUserLocation(Double latitude, Double longitude, String addrStr) {
        //保存或者更新未知信息
        userLocationService.saveOrUpdateUserLocation(latitude, longitude, addrStr, UserHolder.getId());
    }

    /**
     * 附近的人
     */
    public List<NearUserVo> searchUser(String gender, Long distance) {
        //1.获取登录用户的id
        Long loginUserId = UserHolder.getId();
        //2.调用service查询附近的人
        List<Long> idsList = userLocationService.searchUser(loginUserId, distance);

        //3.处理返回的结果
        List<NearUserVo> voList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(idsList)) {
            for (Long uid : idsList) {
                //1.根据id查询用户信息
                UserInfo userInfo = userInfoService.findById(uid);
                //2.排除自己
                if (loginUserId == uid) {
                    continue;
                }

                //3.排除同性
                if (!StrUtil.equals(gender, userInfo.getGender())) {
                    continue;
                }
                //4.组装返回的vo
                NearUserVo vo = new NearUserVo();
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setUserId(userInfo.getId());
                voList.add(vo);
            }
        }

        return voList;
    }


    @Autowired
    private HuanXinTemplate huanXinTemplate;
    /**
     * 打招呼
     */
    public void replyStrangerQuestion(String questionUserId, String reply) {
        //1.获取当前登录用户id
        Long loginUserId = UserHolder.getId();
        //2.查询当前用户的昵称
        UserInfo userInfo = userInfoService.findById(loginUserId);
        //3.查询问题
        Question question = questionService.findByUserId(Long.valueOf(questionUserId));
        //4.构建map数据
        Map<String, String> map = new HashMap<>();
        map.put("userId",loginUserId.toString());//当前登录用户的id
        map.put("nickname",userInfo.getNickname());//当前用户昵称
        if (question == null) {
            map.put("strangerQuestion", "远赴人间惊鸿宴");//问题
        } else {
            map.put("strangerQuestion", question.getStrangerQuestion());//问题
        }
        map.put("reply", reply);//回复
        //5.发送消息
        String json = JSON.toJSONString(map);
        huanXinTemplate.sendMsg(questionUserId, json);
    }

    @Reference
    private FriendService friendService;

    /**
     * 添加联系人
     * @param replyUserId
     */
    public void saveContact(String replyUserId) {
        //1.获取当前登录用户的id
        Long loginUserId = UserHolder.getId();
        //2.调用service保存MongoDB中的关系
        friendService.saveContact(loginUserId, Long.valueOf(replyUserId));
        //3.保存环信的好友关系
        huanXinTemplate.addContacts(loginUserId, Long.valueOf(replyUserId));
    }

    /**
     * 查询好友列表
     */
    public PageBeanVo findContact(Integer pageNumber, Integer pageSize) {
        //1.获取当前用户->用户的id
        Long loginUserId = UserHolder.getId();
        //2.调用service拆一下你好友列表
        PageBeanVo pageBeanVo = friendService.findContact(pageNumber, pageSize, loginUserId);
        //5.数据转换
        List<Friend> friendList = (List<Friend>) pageBeanVo.getItems();
        List<ContactVo> contactVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(friendList)) {
            for (Friend friend : friendList) {
                UserInfo userInfo = userInfoService.findById(friend.getFriendId());//获取好友用户的信息
                ContactVo vo = new ContactVo();
                vo.setUserInfo(userInfo);
                //vo.setId();   //数据的表示 没用
                vo.setUserId(friend.getFriendId() + "");
                contactVoList.add(vo);//存入集合
            }
        }
        //4.重新封装vo
        pageBeanVo.setItems(contactVoList);
        //3.返回对象
        return pageBeanVo;
    }


}
